#include <ESP8266WiFi.h>//安装esp8266arduino开发环境
static WiFiClient espClientAliyun;
static WiFiClient espClientHttp;

#include <ESP8266HTTPClient.h>
HTTPClient http;

#include <SoftwareSerial.h>
SoftwareSerial espSerial(13,12);

#include <AliyunIoTSDK.h>//引入阿里云 IoT SDK
//需要安装crypto库、PubSubClient库

//设置产品和设备的信息，从阿里云设备信息里查看
#define PRODUCT_KEY     "*********"//替换自己的PRODUCT_KEY
#define DEVICE_NAME     "myled"//替换自己的DEVICE_NAME
#define DEVICE_SECRET   "******************"//替换自己的DEVICE_SECRET
#define REGION_ID       "cn-shanghai"//默认cn-shanghai

#define WIFI_SSID       "jianfeng"//替换自己的WIFI
#define WIFI_PASSWD     "123456789"//替换自己的WIFI

unsigned long lastMsMain = 0;
unsigned long lastMsMainHttp = 0;
int static aut_switch=0;
int static atm_switch=0;
String static hour;
String static Url = "http://quan.suning.com/getSysTime.do";

void setup()
{
  Serial.begin(57600);
  espSerial.begin(57600);
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, HIGH);

  //连接到wifi
  wifiInit(WIFI_SSID, WIFI_PASSWD);

  //初始化 iot，需传入 wifi 的 client，和设备产品信息
  AliyunIoTSDK::begin(espClientAliyun, PRODUCT_KEY, DEVICE_NAME, DEVICE_SECRET, REGION_ID);

  http.setTimeout(2000);
  
  //绑定一个设备属性回调，当远程修改此属性，会触发LED函数
  AliyunIoTSDK::bindData("LED",LED);
  AliyunIoTSDK::bindData("IDR", IDR);
  AliyunIoTSDK::bindData("PIR", PIR);
  AliyunIoTSDK::bindData("AUTOTIME", ATM);
  AliyunIoTSDK::bindData("AUTO", AUT);
  AliyunIoTSDK::bindData("Brightness", Brightness);
  AliyunIoTSDK::bindData("CurrentTime", CurrentTime);
  AliyunIoTSDK::bindData("PTL", PTL);
}

void loop()
{
  AliyunIoTSDK::loop();//必要函数

  if (millis() - lastMsMain >= 3000)//每2秒发送一次
  {
    lastMsMain = millis();
    if(espSerial.available()){
//      Serial.println("**********");
      char c=(char)espSerial.read();
//      Serial.println(c);
      if(c=='Q'){
        getAuto(&aut_switch);
      }
      if(c=='Z'){
        getAutoTime(&atm_switch);
      }
      if(c=='W'){
        sendDataToAliyun();
      }
      if(c=='X'){
        int CT=getUnoTime();
        Serial.print("UNO TIME*************");
        Serial.println(CT);
        AliyunIoTSDK::send("CurrentTime",CT);
      }
      if(c=='G'){
        int Bri=getBrightness();
        Serial.print("BRIGHTNESS*************");
        Serial.println(Bri);
        AliyunIoTSDK::send("Brightness",Bri);
      }
      if(c=='V'){
        if(espSerial.read=='F'){
          AliyunIoTSDK::send("VFS",1);
        }
        if(espSerial.read=='S'){
          AliyunIoTSDK::send("VFS",2);
        }
        if(espSerial.read=='N'){
          AliyunIoTSDK::send("VFS",0);
        }
      }
    }
  }
  
  if(atm_switch==1 and (millis() - lastMsMainHttp >= 9000))//每9秒发送一次
  {
    lastMsMainHttp = millis();
    sendHttpTime(); 
  }
}

//wifi 连接
void wifiInit(const char *ssid, const char *passphrase)
{
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, passphrase);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(1000);
    Serial.println("WiFi not Connect");
  }
  Serial.println("Connected to AP");
}

//发送http时间
void sendHttpTime()
{   
    http.begin(espClientHttp,Url);
    int httpCode=http.GET();
    //    Serial.println(httpCode);
    if(httpCode>0){
//      Serial.printf("[HTTP] GET... code: %d\n",httpCode);
      if(httpCode==HTTP_CODE_OK){
        String response=http.getString();
        String hour1=response.substring(24,25);
        String hour2=response.substring(25,26);
        if(hour1=="0"){
          hour=hour2;
        }else{
          hour=hour1+hour2;
        }
//        Serial.println(hour);
        espSerial.print("T"+hour+"E");
      }else{
//        Serial.println("HTTP... failed");
      }
      http.end();
    }
}

int getUnoTime(){
  char c;
  String readTime;
  c=(char)espSerial.read();
  if(c=='X'){
    while(true){
      c=(char)espSerial.read();
      if(c=='Y'){
        int CT=readTime.toInt();
        return CT;
        }else{
        readTime+=c;
      }
    } 
  }
}

int getBrightness(){
  char c;
  String readBri;
  c=(char)espSerial.read();
  if(c=='G'){
    while(true){
      c=(char)espSerial.read();
      if(c=='H'){
        int Bri=readBri.toInt();
        return Bri;
        }else{
        readBri+=c;
      }
    } 
  }
}

void getAutoTime(int* atm_switch){
  if((char)espSerial.read()=='A'){
    if((char)espSerial.read()=='T'){
      if((char)espSerial.read()=='M'){
        if((char)espSerial.read()=='1'){
          *atm_switch=1;
          AliyunIoTSDK::send("AUTOTIME", 1);
        }else{
          *atm_switch=0;
          AliyunIoTSDK::send("AUTOTIME", 0);
        }
      }
    }
  }
}

void getAuto(int* aut_switch){
  if((char)espSerial.read()=='A'){
    if((char)espSerial.read()=='U'){
      if((char)espSerial.read()=='T'){
        if((char)espSerial.read()=='1'){
          *aut_switch=1;
          AliyunIoTSDK::send("AUTO", 1);
        }else{
          *aut_switch=0;
          AliyunIoTSDK::send("AUTO", 0);
        }
      }
    }
  }
}

//获取Uno传来的数据上传到Aliyun
void sendDataToAliyun(){
      int i;
      String readSensor="";
      for(i=0;i<4;i++){
        char c=(char)espSerial.read();
        readSensor+=c;
      }
      Serial.print("DATA STRINGS***********");
      Serial.println(readSensor);
      if(readSensor=="LED1"){
        AliyunIoTSDK::send("LED",1);
        readSensor="";
      }
      if(readSensor=="LED0"){
        AliyunIoTSDK::send("LED",0);
        readSensor="";
      }
      if(readSensor=="IDR1"){
        Serial.println("IDR1");
        AliyunIoTSDK::send("IDR",1);
        readSensor="";
      }
      if(readSensor=="IDR0"){
        Serial.println("IDR0");
        AliyunIoTSDK::send("IDR",0);
        readSensor="";
      }
      if(readSensor=="PIF1"){
        Serial.println("PIF1");
        AliyunIoTSDK::send("PIF",1);
        readSensor="";
      }
      if(readSensor=="PIF0"){
        Serial.println("PIF0");
        AliyunIoTSDK::send("PIF",0);
        readSensor="";
      }
      if(readSensor=="PIS1"){
        Serial.println("PIS1");
        AliyunIoTSDK::send("PIS",1);
        readSensor="";
      }
      if(readSensor=="PIS0"){
        Serial.println("PIS0");
        AliyunIoTSDK::send("PIS",0);
        readSensor="";
      }
}


//灯的属性修改的回调函数
void LED(JsonVariant L)//固定格式，修改参数l
{
  int LED = L["LED"];//参数l
  if (LED == 1)
  {
    espSerial.print("DLED1");
  }
  else 
  {
    espSerial.print("DLED0");
  }
}

void IDR(JsonVariant L)//固定格式，修改参数l
{
  int IDR = L["IDR"];//参数l
  if (IDR == 1)
  {
    espSerial.print("DIDR1");
  }
  else 
  {
    espSerial.print("DIDR0");
//    digitalWrite(LedPin, HIGH);
//    delay(1000);
//    digitalWrite(LedPin,LOW);
//    delay(1000);
  }
}

void PIR(JsonVariant L)//固定格式，修改参数l
{
  int PIR= L["PIR"];//参数l
  if (PIR== 1)
  {
    espSerial.print("DPIR1");
  }
  else 
  {
    espSerial.print("DPIR0");
  }
}

void ATM(JsonVariant L)//固定格式，修改参数l
{
  int ATM= L["AUTOTIME"];//参数l
  if (ATM== 1)
  {
    espSerial.print("DATM1");
  }
  else 
  {
    espSerial.print("DATM0");
  }
}

void AUT(JsonVariant L)//固定格式，修改参数l
{
  int AUT= L["AUTO"];//参数l
  if (AUT== 1)
  {
    espSerial.print("DAUT1");
  }
  else 
  {
    espSerial.print("DAUT0");
  }
}

void PTL(JsonVariant L)//固定格式，修改参数l
{
  int PTL= L["PTL"];//参数l
  if (PTL== 1)
  {
    espSerial.print("DPTL1");
  }
//  else { espSerial.print("DPTL0"); }    因为PTL仅为变为1时作用，所以变为0时不必传输给单片机
}

void Brightness(JsonVariant L){
  int Brightness= L["Brightness"];
  int i;
  for(i=0;i<256;i++){
    if(Brightness==i){
      String temp=String(Brightness);
      espSerial.print("G"+temp+"H");
      break;
    }
  }
}

void CurrentTime(JsonVariant L){
  int CurrentTime= L["CurrentTime"];
  int i;
  for(i=0;i<24;i++){
    if(CurrentTime==i){
      String temp=String(CurrentTime);
      espSerial.print("T"+temp+"E");
      break;
    }
  }
}
